﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using GeneralDFS.BusinessLogical.Nodes;
using GeneralDFS.BusinessLogical.Statistics;
using GeneralDFS.Common.Network;
using GeneralDFS.Interface.Agent;
using Microsoft.VisualBasic.Devices;
using NIF.MobileActors.Core;
using NIF.MobileActors.Hosts;
using GeneralDFS.DataEntity.Nodes;
using GeneralDFS.DataEntity.Statistics;

namespace AgentTest
{
    [Serializable]
    public class SearchNodesActor : ActorBase<IEntry>, IEntry
    {

        private Queue<IPEndPoint> _hosts;
        public Queue<IPEndPoint> Hosts
        {
            get { return _hosts; }
            set { _hosts = value; }
        }

        private IPEndPoint localHost;
        public IPEndPoint LocalHost
        {
            get { return localHost; }
            set { localHost = value; }
        }
        private bool isLastHost = false;
        public bool IsLastHost
        {
            get { return isLastHost; }
        }
        private bool isFirstHost = true;
        public bool IsFirstHost
        {
            get { return isFirstHost; }
        }
        public List<NameNodeStatistics> NameNodeStatistics = new List<NameNodeStatistics>();

        public void Excute()
        {
            PhysicalParameter physicalPara = new PhysicalParameter();

            var info = new ComputerInfo();
            var cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            cpu.NextValue();


            if (_hosts.Count == 0 && isFirstHost == true )
            {
                Print("There is not any nodes");
            }
            else if (isFirstHost && _hosts.Count != 0)
            {
                Print("Start go to the Nodes to search Information....");
                var ipEndPoint = _hosts.Dequeue();
                isFirstHost = false;
                RemotingHost.DispatchActorTo(this, ipEndPoint);
            }
            else if (!isFirstHost)
            {
                if (RemotingHost.Node != null && RemotingHost.Node is NameNode)
                {
                    NameNodeStatistics statistic = new NameNodeStatistics(RemotingHost.Node);
                    statistic.Excute();
                    //int i = 1;
                    double j=0;
                    //while (j==0)
                    //{
                        //Print(i.ToString());
                        j=cpu.NextValue();
                        //i++;
                    //}
                    statistic.Cpu = Math.Round(j, 2, MidpointRounding.AwayFromZero).ToString();
                    statistic.Memory = Utility.ConvertBytes(physicalPara.GetPhysicalMemSize(), 3).ToString();
                    statistic.HardDiskSize = Utility.ConvertBytes(physicalPara.GetSizeOfDiskSize(), 3).ToString();
                    // machineCounter.HardDiskSpace
                    NameNodeStatistics.Add(statistic);

                    Print("=======");
                    Print(statistic.Cpu);
                    Print(statistic.Memory + "G");
                    Print(statistic.HardDiskSize + "G");
                    try
                    {

                        if (_hosts.Count == 0)
                        {
                            Console.WriteLine("you are the last one");
                            isLastHost = true;
                            isFirstHost = true;
                            RemotingHost.DispatchActorTo(this, localHost);
                            return;
                        }
                        else
                        {
                            var ipEndPoint = _hosts.Dequeue();
                            RemotingHost.DispatchActorTo(this, ipEndPoint);
                        }
                    }
                    catch (Exception ex)
                    {
                        Print(ex.ToString());
                    }

                }


            }
            if (isLastHost)
            {   Console.WriteLine("you have finished:");

                foreach (var nameNodeStatisticse in NameNodeStatistics)
                {
                  Print(nameNodeStatisticse.NameNodeInfo.ServerName.ToString());
                  Print(nameNodeStatisticse.NameNodeInfo.Ip.ToString());
                  Print(nameNodeStatisticse.NameNodeInfo.RpcPort.ToString());
                  Print(nameNodeStatisticse.NameNodeInfo.AgentRpcPort.ToString());
                  Print(nameNodeStatisticse.Cpu);
                  Print(nameNodeStatisticse.Memory + "G");
                  Print(nameNodeStatisticse.HardDiskSize + "G");
                    Print("");
                }

            }
        }
        protected override void Receive(Action<IEntry> message)
        {
            message(this);
        }

        protected override void ResumeState(IActor actNewState)
        {
            Debug.Assert(actNewState is SearchNodesActor);
            var act = actNewState as SearchNodesActor;
            _hosts = act.Hosts;
            isLastHost = act.isLastHost;
            isFirstHost = act.isFirstHost;
            localHost = act.localHost;
            NameNodeStatistics = act.NameNodeStatistics;
        }

        public override void OnDispatched()
        {
            ActorProxy<IEntry> proxy = RemotingHost.LocalFacade.GetActorProxy<IEntry>(this.ID);
            proxy.Post(h => h.Excute());
        }
        public void Print(string message)
        {
            Console.WriteLine(message);
        }

    }
}
